// 定义类型
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";

interface RequestConfig {
    url: string;
    method?: HttpMethod;
    data?: any;
    params?: any;
    header?: Record<string, string>;
    loading?: boolean;
    loadingText?: string;
    isAuth?: boolean;
    timeout?: number;
    [key: string]: any;
}

interface ResponseData<T = any> {
    code: number;
    message?: string;
    data: T;
    [key: string]: any;
}

interface HttpResponse<T = any> {
    statusCode: number;
    data: ResponseData<T>;
    header: any;
    cookies: Array<string>;
}

// 请求基地址
const BASE_URL: string = import.meta.env.VITE_API_BASE_URL || "http://localhost:3000";

// 默认配置
const DEFAULT_CONFIG: RequestConfig = {
    url: "",
    method: "GET",
    data: {},
    params: {},
    header: {
        "Content-Type": "application/json"
    },
    loading: true,
    loadingText: "加载中...",
    isAuth: true,
    timeout: 10000
};

// 请求队列（用于防止重复请求）
const requestQueue = new Map<string, boolean>();

/**
 * 核心请求函数
 * @param config 请求配置
 * @returns Promise
 */
async function coreRequest<T = any>(config: RequestConfig): Promise<ResponseData<T>> {
    // 合并配置
    const mergedConfig: RequestConfig = {
        ...DEFAULT_CONFIG,
        ...config,
        header: {
            ...DEFAULT_CONFIG.header,
            ...(config.header || {})
        }
    };

    // 处理GET请求的params
    if (mergedConfig.method === "GET" && mergedConfig.params) {
        mergedConfig.data = mergedConfig.params;
    }

    // 请求唯一标识（用于防止重复请求）
    const requestKey = `${mergedConfig.method}_${mergedConfig.url}_${JSON.stringify(mergedConfig.data)}`;

    // 检查是否重复请求
    if (requestQueue.has(requestKey)) {
        const errMsg = "重复请求，已取消";
        console.warn(errMsg);
        return Promise.reject(new Error(errMsg));
    }

    // 添加到请求队列
    requestQueue.set(requestKey, true);

    try {
        // 请求拦截
        const processedConfig = await requestInterceptor(mergedConfig);

        // 显示加载框
        if (processedConfig.loading) {
            uni.showLoading({
                title: processedConfig.loadingText,
                mask: true
            });
            setTimeout(function () {
                uni.hideLoading();
            }, 12000);
        }

        // 发起请求
        const response = await uniRequest<T>(processedConfig);

        // 响应拦截
        const processedResponse = await responseInterceptor<T>(response, processedConfig);

        return processedResponse;
    } catch (error) {
        // 错误处理
        errorHandler(error as Error, config);
        return Promise.reject(error);
    } finally {
        // 从请求队列移除
        requestQueue.delete(requestKey);
        // 隐藏加载框
        if (config.loading) {
            uni.hideLoading();
        }
    }
}

/**
 * uni.request 的 Promise 封装
 * @param config 请求配置
 * @returns Promise
 */
function uniRequest<T = any>(config: RequestConfig): Promise<HttpResponse<T>> {
    return new Promise((resolve, reject) => {
        uni.request({
            url: config.url.startsWith("http") ? config.url : BASE_URL + config.url,
            method: config.method as any,
            data: config.data,
            header: config.header,
            timeout: config.timeout,
            success: res => resolve(res as HttpResponse<T>),
            fail: err => reject(err)
        });
    });
}

/**
 * 请求拦截器
 * @param config 请求配置
 * @returns 处理后的配置
 */
async function requestInterceptor(config: RequestConfig): Promise<RequestConfig> {
    // 在这里可以添加全局请求逻辑，例如添加token
    if (config.isAuth) {
        const token = uni.getStorageSync("token");
        if (token) {
            config.header = config.header || {};
            config.header.Authorization = `Bearer ${token}`;
        } else {
            // 如果没有token且需要认证，可以在这里处理跳转登录等逻辑
            console.warn("缺少认证token");
        }
    }

    return config;
}

/**
 * 响应拦截器
 * @param response 响应结果
 * @param config 请求配置
 * @returns 处理后的响应数据
 */
async function responseInterceptor<T = any>(
    response: HttpResponse<T>,
    config: RequestConfig
): Promise<ResponseData<T>> {
    const { statusCode, data } = response;
    // 状态码判断
    if (statusCode === 200 || statusCode === 201) {
        uni.hideLoading();
        return data;
        // 这里根据你的API设计调整判断逻辑
        if (data.code === 0 || data.success) {
            // 成功响应
            return data;
        } else {
            // 业务错误处理
            const error = new Error(data.message || "业务错误") as any;
            error.code = data.code;
            error.data = data;
            throw error;
        }
    } else {
        // HTTP错误处理
        const error = new Error(`请求错误，状态码：${statusCode}`) as any;
        error.statusCode = statusCode;
        error.data = data;
        throw error;
    }
}

/**
 * 错误处理器
 * @param error 错误对象
 * @param config 请求配置
 */
function errorHandler(error: any, config: RequestConfig): void {
    console.error("请求错误:", error);

    // 根据状态码处理不同错误
    if (error.statusCode) {
        switch (error.statusCode) {
            case 401:
                // 未授权，跳转登录页
                uni.navigateTo({
                    url: "/pages/login/login"
                });
                break;
            case 403:
                uni.showToast({
                    title: "无访问权限",
                    icon: "none"
                });
                break;
            case 404:
                uni.showToast({
                    title: "资源不存在",
                    icon: "none"
                });
                break;
            case 500:
                uni.showToast({
                    title: "服务器错误",
                    icon: "none"
                });
                break;
            default:
                uni.showToast({
                    title: error.message || "请求失败",
                    icon: "none"
                });
        }
    } else if (error.message) {
        // 业务错误
        uni.showToast({
            title: error.message || "操作失败",
            icon: "none"
        });
    }

    // 可以在这里添加错误上报逻辑
}

/**
 * GET请求
 * @param url 请求地址
 * @param params 请求参数
 * @param config 额外配置
 * @returns Promise
 */
export function get<T = any>(
    url: string,
    params?: any,
    config?: Omit<RequestConfig, "url" | "method" | "data">
): Promise<ResponseData<T>> {
    return coreRequest<T>({
        url,
        method: "GET",
        params,
        ...config
    });
}

/**
 * POST请求
 * @param url 请求地址
 * @param data 请求数据
 * @param config 额外配置
 * @returns Promise
 */
export function post<T = any>(
    url: string,
    data?: any,
    config?: Omit<RequestConfig, "url" | "method" | "data">
): Promise<ResponseData<T>> {
    return coreRequest<T>({
        url,
        method: "POST",
        data,
        ...config
    });
}

/**
 * PUT请求
 * @param url 请求地址
 * @param data 请求数据
 * @param config 额外配置
 * @returns Promise
 */
export function put<T = any>(
    url: string,
    data?: any,
    config?: Omit<RequestConfig, "url" | "method" | "data">
): Promise<ResponseData<T>> {
    return coreRequest<T>({
        url,
        method: "PUT",
        data,
        ...config
    });
}

/**
 * DELETE请求
 * @param url 请求地址
 * @param data 请求数据
 * @param config 额外配置
 * @returns Promise
 */
export function del<T = any>(
    url: string,
    data?: any,
    config?: Omit<RequestConfig, "url" | "method" | "data">
): Promise<ResponseData<T>> {
    return coreRequest<T>({
        url,
        method: "DELETE",
        data,
        ...config
    });
}

/**
 * 通用请求方法
 * @param config 请求配置
 * @returns Promise
 */
export function request<T = any>(config: RequestConfig): Promise<ResponseData<T>> {
    return coreRequest<T>(config);
}

// 导出所有方法
export default {
    request,
    get,
    post,
    put,
    delete: del
};

// import { get, post } from '@/utils/request'

// // 定义响应数据类型
// interface UserInfo {
//   id: number
//   name: string
//   email: string
//   avatar: string
// }

// // GET请求
// async function fetchUserInfo(userId: number) {
//   try {
//     const res = await get<UserInfo>('/user/info', { id: userId })
//     console.log('用户信息:', res.data)
//     return res.data
//   } catch (error) {
//     console.error('获取用户信息失败:', error)
//     throw error
//   }
// }

// // POST请求
// interface LoginParams {
//   username: string
//   password: string
// }

// interface LoginResponse {
//   token: string
//   expiresIn: number
// }

// async function login(params: LoginParams) {
//   try {
//     const res = await post<LoginResponse>('/user/login', params, {
//       loadingText: '登录中...',
//       isAuth: false // 登录接口不需要认证
//     })
//     console.log('登录成功:', res.data)
//     // 存储token
//     uni.setStorageSync('token', res.data.token)
//     return res.data
//   } catch (error) {
//     console.error('登录失败:', error)
//     throw error
//   }
// }
